#![allow(dead_code)]
extern crate printpdf;
extern crate image;

use printpdf::*;
use std::fs::File;
use std::iter::FromIterator;


pub fn export_pdf_with_images(_sheet_name:String, headers:Vec<String>,
		contents:Vec<Vec<String>>, is_images:Vec<bool>)->Vec<u8>{
	let mut page_width = 210.0;
	let mut page_height = 297.0;
	let mut pagesize = 10;
	if Vec::len(&headers) > 8 {
		page_width = 297.0;
		page_height = 210.0;
		pagesize = 5;
	}
	let (doc, page1, layer1) = PdfDocument::new("PDF export", Mm(page_width), Mm(page_height), "Layer 1");
	let font = doc.add_external_font(File::open("./template/fonts/msyh.ttf").unwrap()).unwrap();

	let mut pageindex = 0;
	let records_count = Vec::len(&contents);
	while pageindex * pagesize < records_count{
		if pageindex == 0{
			let current_layer = doc.get_page(page1).get_layer(layer1);
			let mut pageend = (pageindex+1) * pagesize;
			if pageend>records_count {pageend = records_count;}
			write_header_row(font.clone(),current_layer.clone(),page_width.clone(),page_height.clone(),headers.clone(),is_images.clone());
			write_content_rows(font.clone(),current_layer,page_width.clone(),page_height.clone(),contents[pageindex * pagesize..pageend].to_vec(),is_images.clone());
		}else {
			let (pagen, layern) = doc.add_page(Mm(page_width), Mm(page_height),"Layer ".to_owned()+&pageindex.to_string());
			let current_layer = doc.get_page(pagen).get_layer(layern);
			let mut pageend = (pageindex+1) * pagesize;
			if pageend>records_count {pageend = records_count;}
			write_header_row(font.clone(),current_layer.clone(),page_width.clone(),page_height.clone(),headers.clone(),is_images.clone());
			write_content_rows(font.clone(),current_layer,page_width.clone(),page_height.clone(),contents[pageindex * pagesize..pageend].to_vec(),is_images.clone());
		}
		pageindex += 1;
	}
	doc.save_to_bytes().unwrap()
}

fn write_header_row(font:IndirectFontRef,layer:PdfLayerReference, page_width:f64,page_height:f64,headers:Vec<String>, _is_images:Vec<bool>){
	let neat_width = page_width - 20.0;
	let neat_height = page_height - 10.0;
	let col_width = neat_width/(Vec::len(&headers) as f64);
	let row_height = (page_height-20.0)/11.0;
	let _outline_color = Color::Rgb(Rgb::new(1.0, 0.0, 0.0, None));
	let innerline_color = Color::Rgb(Rgb::new(0.0, 0.0, 0.0, None));

	let mut head_line = Line::from_iter(vec![
		(Point::new(Mm(10.0), Mm(neat_height)), false),
		(Point::new(Mm(neat_width+10.0), Mm(neat_height)), false)]);
	head_line.set_stroke(true);
	layer.set_outline_color(_outline_color);
	layer.set_outline_thickness(2.0);
	layer.add_shape(head_line);

	let mut row_inner_head_line = Line::from_iter(vec![
		(Point::new(Mm(10.0), Mm(neat_height)), false),
		(Point::new(Mm(10.0), Mm(neat_height-row_height)), false)]);
	row_inner_head_line.set_stroke(true);
	layer.set_outline_color(innerline_color.clone());
	layer.set_outline_thickness(2.0);
	layer.add_shape(row_inner_head_line);
	let mut col_index = 1.0;
	for item in headers {
		let mut row_inner_line = Line::from_iter(vec![
			(Point::new(Mm(10.0+col_index*col_width), Mm(neat_height)), false),
			(Point::new(Mm(10.0+col_index*col_width), Mm(neat_height-row_height)), false)]);
		row_inner_line.set_stroke(true);
		// layer.set_outline_color(innerline_color.clone());
		layer.begin_text_section();
		layer.set_outline_thickness(1.0);
		layer.add_shape(row_inner_line);
		layer.set_font(&font, 12.0);
		layer.set_text_cursor(Mm(10.0+(col_index-1.0)*col_width+2.0), Mm(neat_height-1.0/3.0*row_height+2.0));
		layer.set_line_height(row_height);
		layer.set_word_spacing(col_width);
		layer.set_character_spacing(1.0);
		layer.set_text_rendering_mode(TextRenderingMode::Fill);
		layer.write_text(item,&font);
		layer.end_text_section();
		col_index += 1.0;
	}

	let mut row_bottom_line = Line::from_iter(vec![
		(Point::new(Mm(10.0), Mm(neat_height-row_height)), false),
		(Point::new(Mm(neat_width+10.0), Mm(neat_height-row_height)), false)]);
	row_bottom_line.set_stroke(true);
	layer.add_shape(row_bottom_line);
}

fn write_content_rows(font:IndirectFontRef,layer:PdfLayerReference, page_width:f64,page_height:f64,contents:Vec<Vec<String>>,is_images:Vec<bool>){
	let neat_width = page_width - 20.0;
	let neat_height = page_height - 10.0;
	let col_width = neat_width/(Vec::len(&contents.get(0).expect("Empty contents.")) as f64);
	let row_height = (page_height-20.0)/11.0;
	let _outline_color = Color::Rgb(Rgb::new(1.0, 0.0, 0.0, None));
	let innerline_color = Color::Rgb(Rgb::new(0.0, 0.0, 0.0, None));

	let mut row_index = 1.0;
	for row in contents{
		let mut row_inner_head_line = Line::from_iter(vec![
			(Point::new(Mm(10.0), Mm(neat_height-row_index*row_height)), false),
			(Point::new(Mm(10.0), Mm(neat_height-(row_index+1.0)*row_height)), false)]);
		row_inner_head_line.set_stroke(true);
		layer.set_outline_color(innerline_color.clone());
		layer.set_outline_thickness(2.0);
		layer.add_shape(row_inner_head_line);
		let mut col_index = 1.0;
		for item in row {
			let mut row_inner_line = Line::from_iter(vec![
				(Point::new(Mm(10.0+col_index*col_width), Mm(neat_height-row_index*row_height)), false),
				(Point::new(Mm(10.0+col_index*col_width), Mm(neat_height-(row_index+1.0)*row_height)), false)]);
			row_inner_line.set_stroke(true);
			// layer.set_outline_color(innerline_color.clone());
			layer.begin_text_section();
			layer.set_outline_thickness(1.0);
			layer.add_shape(row_inner_line);
			layer.set_font(&font, 12.0);
			layer.set_text_cursor(Mm(10.0+(col_index-1.0)*col_width+2.0), Mm(neat_height-1.0/3.0*row_height+2.0-row_index*row_height));
			layer.set_line_height(row_height);
			layer.set_word_spacing(col_width);
			layer.set_character_spacing(1.0);
			layer.set_text_rendering_mode(TextRenderingMode::Fill);
			if *(is_images.get((col_index -1.0) as usize).expect("IsImages is none.")){
				if item == "" || item.len() == 0 {
					layer.write_text("".to_string(),&font);
				}else{
					let img = get_image(item);
					match img {
						Some(img) => {
							let mut img_t_form = ImageTransform::default();
							let _width = img.image.width.0 as f64 ;
							let height = img.image.height.0 as f64;
							let dpi = 30.0/2.54;
							let ratio = row_height / height * dpi;

							img_t_form.translate_x = Some(Mm(10.0+(col_index-1.0)*col_width+2.0));
							img_t_form.translate_y = Some(Mm(neat_height-row_height-row_index*row_height));
							img_t_form.scale_x = Some(ratio);
							img_t_form.scale_y = Some(ratio);
							img_t_form.dpi = Some(300.0);
							img.add_to_layer(layer.clone(), img_t_form);
						},
						None => {
							layer.write_text("".to_string(),&font);
						}
					}
				}
			}else {
				layer.write_text(item,&font);
			}
			layer.end_text_section();
			col_index += 1.0;
		}

		let mut row_bottom_line = Line::from_iter(vec![
			(Point::new(Mm(10.0), Mm(neat_height- (row_index+1.0)*row_height)), false),
			(Point::new(Mm(neat_width+10.0), Mm(neat_height-(row_index+1.0)*row_height)), false)]);
		row_bottom_line.set_stroke(true);
		layer.add_shape(row_bottom_line);
		row_index += 1.0;
	}
}

fn get_image(data:String)->Option<Image>{
	let image_data = base64::decode(data.clone());

	match image_data {
		Err(_) => {
			None
		},
		Ok(image_data) => {
			let img=image::load_from_memory(&image_data).unwrap();
			let image = Image::from_dynamic_image(&img);
			Some(image)
		}
	}
}
